サプレッションリストのメールアドレスが 1000 件以上の場合の全件取得のやり方

サプレッションリストのメールアドレスが 1000 件以上の場合の全件取得のやり方

AWS 公式ブログ「How to list over 1000 email addresses from account-level suppression list 」の Python コードを使って全件取得できます。
Clock Icon2025.01.16

検証で サプレッションリストのメールアドレス(1000件以上)一覧を取得する機会がありましたので、手順を共有します。
今回はあくまで検証なので、例として、1万件のメールアドレスをサプレッションリストに一括登録し、その後、以下公式ブログの Python コードで全件取得、最後に後片付けとして登録済みの1万件のアドレスを一括削除します。

https://aws.amazon.com/jp/blogs/messaging-and-targeting/how-to-list-over-1000-email-addresses-from-account-level-suppression-list/

メールアドレスを 追加/削除 するための CSV を作成する

1万件のメールアドレスを SES の一括追加機能でサプレッションリストに追加します。一括追加機能の詳細は下記公式ブログを参照ください

メールアドレスを一括で追加するには、追加するメールアドレスの一覧が記載された CSV または JSON を S3 にアップロードする必要があります。
また、一括で削除するためにも同様に削除するアドレスの一覧を CSV または JSON にまとめる必要があります。
今回は以下の Python コードで追加用と削除用の CSV を作成します。

gen_test_data.py

import random

# 2つのファイルを同時に書き込みモードでオープン
with open('add_address_list.csv', 'w') as f1, open('delete_address_list.csv', 'w') as f2:
    x = 10000  # x=<メールアドレス件数>
    # x行のデータを生成
    for i in range(0, x):
        status = random.choice(['BOUNCE', 'COMPLAINT'])
        # ステータス付きのCSVに書き込み
        f1.write(f"hoge{i}@example.com,{status}\n")
        # ステータスなしのCSVに書き込み
        f2.write(f"hoge{i}@example.com\n")

もし、メールアドレスを10件のみ追加したいのであれば上記コード内の変数 x を 10 にしてください。
今回はテスト用で1万件登録したいので、10000 として生成します。
できあがった CSV は以下です。ヘッダーは要りません。

add_address_list.csv

hoge0@example.com,COMPLAINT
hoge1@example.com,COMPLAINT
hoge2@example.com,COMPLAINT
...
hoge9997@example.com,BOUNCE
hoge9998@example.com,COMPLAINT
hoge9999@example.com,BOUNCE

delete_address_list.csv

hoge0@example.com
hoge1@example.com
hoge2@example.com
...
hoge9997@example.com
hoge9998@example.com
hoge9999@example.com

上記 add_address_list.csv の2列目には "COMPLAINT" or "BOUNCE" のどちらかの文字列を入れます。これはサプレッションリストの追加理由である苦情またはバウンスを表しています。

サプレッションリストにメールアドレスを一括追加する

※一括追加はサンドボックス環境からは実施できないので、もしサンドボックスを使用している方は以下ブログを参考に本番環境に移行してからお試しください。
https://dev.classmethod.jp/articles/amazon-ses-production-access-request/

「SES コンソール -> サプレッションリスト -> 一括アクション -> Eメールアドレスの一括追加」 を選択

スクリーンショット 2025-01-16 21.42.16

「ファイルからインポート」を選び、前項で作成した add_address_list.csv を選びます。
なお、このファイルは S3 にアップロードされるので、テストデータアップロード用の適当な S3 バケットを作成しておいてください。
準備ができたら、右下の「Eメールアドレスの追加」を選択。

スクリーンショット 2025-01-16 21.47.16

"一括アクション" タブのステータスが完了になれば OK です。
スクリーンショット 2025-01-16 21.53.48

"サプレッションリスト" タブにもきちんと登録されていることがわかります。(順不同なのが気になりますが、、おそらく全部登録されているはずです。次項で一覧取得して確認します)

スクリーンショット 2025-01-16 21.55.21

サプレッションリストのメールアドレス全件取得

前項で登録したメールアドレス 1万件を取得します。
公式ブログ How to list over 1000 email addresses from account-level suppression list
の Python コードを使用します。

実際のコードは以下です。公式ブログでは CloudShell で動かしていますが、AWS へのアクセス環境があればいいので、自分はローカル環境(Python 3.9.6)で実行しました。

List_Account_Level.py

import boto3
from datetime import datetime
import json

def showTimestamp(results):
    updated_results = []
    for eachAddress in results:
        updated_address = eachAddress.copy()
        updated_address['LastUpdateTime'] = eachAddress['LastUpdateTime'].strftime("%m/%d/%Y, %H:%M:%S")
        updated_results.append(updated_address)
    return updated_results

def get_resources_from(supression_details):
    results = supression_details['SuppressedDestinationSummaries']
    next_token = supression_details.get('NextToken', None)
    return results, next_token

def main():
    client = boto3.client('sesv2')
    next_token = ''  # Variable to hold the pagination token
    results = []   # List for the entire resource collection
    # Call the `list_suppressed_destinations` method in a loop

    while next_token is not None:
        if next_token:
            suppression_response = client.list_suppressed_destinations(
                PageSize=1000,
                NextToken=next_token
            )
        else:
            suppression_response = client.list_suppressed_destinations(
                PageSize=1000
            )
        current_batch, next_token = get_resources_from(suppression_response)
        results += current_batch

    results = showTimestamp(results)

    print(json.dumps(results, indent=2, sort_keys=False))

if __name__ == "__main__":
    main()

コード実行

% Python3 List_Account_Level.py >> Email_Addresses_List.json

実行した結果、メールアドレス一覧が取得された以下の JSON ファイル Email_Addresses_List.json が得られました。
ブログでは行数を示すことができずわかりづらいのですが jsonファイルの合計行は 50002 行ありました。
ファイルの先頭と末尾は以下のようにリストの括弧なので、実質 50000行となり、この JSON では 1 メールアドレスあたり 5行分使用しているので、50000 / 5 = 10000(件) のアドレスが取得できている ことがわかりました。

Email_Addresses_List.json

[
  {
    "EmailAddress": "hoge5983@example.com",
    "Reason": "COMPLAINT",
    "LastUpdateTime": "01/16/2025, 21:50:40"
  },
  {
    "EmailAddress": "hoge5131@example.com",
    "Reason": "BOUNCE",
    "LastUpdateTime": "01/16/2025, 21:50:43"
  },

(中略)

  {
    "EmailAddress": "hoge6606@example.com",
    "Reason": "BOUNCE",
    "LastUpdateTime": "01/16/2025, 21:50:42"
  },
  {
    "EmailAddress": "hoge5342@example.com",
    "Reason": "COMPLAINT",
    "LastUpdateTime": "01/16/2025, 21:50:39"
  }
]

※なお、全件取得の Python コード実行時に取得するメールアドレスの数が多く API リクエスト制限超過のエラー(TooManyRequestsException)などが発生する場合があります。
その際は、下記ブログを参考に AWS_MAX_ATTEMPTS パラメータを上げるなどすると改善される場合があるのでお試しください。
https://dev.classmethod.jp/articles/tsnote-aws-cli-too-many-requests-exception/

メールアドレスの一括削除

検証を終えたので、登録した1万件のメールアドレスを一括削除します。
手順は一括追加の場合と同じです。

「SES コンソール -> サプレッションリスト -> 一括アクション -> Eメールアドレスの一括削除」 を選択

スクリーンショット 2025-01-16 22.23.26

「ファイルからインポート」を選び、前述の delete_address_list.csv を選び、「E メールアドレスの削除」を実行。

スクリーンショット 2025-01-16 22.26.54

ステータスが完了になれば OK です。
スクリーンショット 2025-01-16 22.30.01

先ほど追加したサプレッションリストが全て削除されてました。これで後片付けも完了です。
スクリーンショット 2025-01-16 22.30.47

終わりに

今回は、サプレッションリストのメールアドレスが1000件以上の時に全件取得するやり方を紹介しました。
Python プログラムを動かすだけでできるのはとても手軽で便利ですね。一括登録なんて機能もあったんだーと今回の検証でわかりました。
本記事がどなたかのお役に立てば幸いです。

参考文献

https://aws.amazon.com/jp/blogs/messaging-and-targeting/how-to-list-over-1000-email-addresses-from-account-level-suppression-list/
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/sending-email-suppression-list.html#sending-email-suppression-list-manual-add-bulk
https://dev.classmethod.jp/articles/amazon-ses-production-access-request/
https://dev.classmethod.jp/articles/tsnote-aws-cli-too-many-requests-exception/

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.